// QtCore
#include <QtCore/QTextCodec>
#include <QtCore/QTextStream>
#include <QtCore/QCoreApplication>
// Локальные
#include "log.h"
#include "settings.h"
#include "cylinder_cone_tt.h"

#if !defined(QT_NO_DEBUG)
void HackedMessageOutput(QtMsgType msg_type, const char *msg)
{
    switch(msg_type)
    {
    case QtFatalMsg:    qFatal(msg);    break;
    case QtDebugMsg:    qDebug(msg);    break;
//    case QtWarningMsg:  qWarning(msg);  break;
    case QtCriticalMsg: qCritical(msg); break;
    }
}
#endif

//================================================================================================================================
//================================================================================================================================
int main(int argc, char *argv[])
{
#if !defined(QT_NO_DEBUG)
    qInstallMsgHandler(HackedMessageOutput);
#endif

    QCoreApplication app(argc, argv);
    app.setOrganizationName("BlackSoft"); // :)
    app.setApplicationName("CylinderConeTt");
    app.setApplicationVersion("1.0.0");

    QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));

    //****************************************************************************************************************************
    //****************************************************************************************************************************
    QTextStream cout(stdout);
    QTextStream cin(stdin);
    cout.setCodec(QTextCodec::codecForName("IBM866"));
    cin.setCodec(QTextCodec::codecForName("IBM866"));

    Log::init(300000, qApp->applicationDirPath() + "log.txt");

    Settings::init();

    if(!Settings::instance()->exist("AppVersion"))
    {
        //************************************************************************************************************************
        // Настройки программы.
        //************************************************************************************************************************
        Settings::instance()->setSetting("AppVersion", qApp->applicationVersion());
        Settings::instance()->setSetting("OutputPath", "./output");

        //************************************************************************************************************************
        // Настройки решателя.
        //************************************************************************************************************************
        Settings::instance()->setSetting("Solver/OtputStep", 10);
        Settings::instance()->setSetting("Solver/ResumeFrom", -1);

        //************************************************************************************************************************
        //************************************************************************************************************************
        Settings::instance()->setSetting("Time/TimeLayers", 20000);
        Settings::instance()->setSetting("Time/TimeStep", 1.5);

        //************************************************************************************************************************
        //************************************************************************************************************************
        Settings::instance()->setSetting("Physics/CrystallizationTemperature", 1685);
        Settings::instance()->setSetting("Physics/MaxTemperature", 1723.16);
        Settings::instance()->setSetting("Physics/RodTemperature", 0);          //Такая же как и температура в горячей зоне печи.
        Settings::instance()->setSetting("Physics/TemperatureGradient", 34.13);
        Settings::instance()->setSetting("Physics/CrucibleSpeed", 1.4063);

        //************************************************************************************************************************
        //************************************************************************************************************************
        Settings::instance()->setSetting("Math/SlaeIters", 1000);
        Settings::instance()->setSetting("Math/SlaeResidual", 1e-10);
        Settings::instance()->setSetting("Math/NonlinIters", 500);
        Settings::instance()->setSetting("Math/NonlinResidual", 1e-7);
        Settings::instance()->setSetting("Math/FrontHalfwidth", 0.05);
        Settings::instance()->setSetting("Math/MinCrystalHeight", 0.);

        //************************************************************************************************************************
        //************************************************************************************************************************
        Settings::instance()->setSetting("Si(Solid)/Density", 2550.0);
        Settings::instance()->setSetting("Si(Solid)/HeatCapacity", 714.0);
        Settings::instance()->setSetting("Si(Solid)/HeatConductivity", 30.15);

        //************************************************************************************************************************
        //************************************************************************************************************************
        Settings::instance()->setSetting("Si(Liquid)/Density", 2550.0);
        Settings::instance()->setSetting("Si(Liquid)/MolarMass", 28.0855);
        Settings::instance()->setSetting("Si(Liquid)/Viscosity", 3.48e-7);
        Settings::instance()->setSetting("Si(Liquid)/HeatCapacity", 1099.95);
        Settings::instance()->setSetting("Si(Liquid)/Expansiveness", 6.68e-5);
        Settings::instance()->setSetting("Si(Liquid)/HeatConductivity", 42.9);
        Settings::instance()->setSetting("Si(Liquid)/CrystallizationHeat", 1.1053152e6);

        //************************************************************************************************************************
        //************************************************************************************************************************
        Settings::instance()->setSetting("C/Density", 1820.0);
        Settings::instance()->setSetting("C/HeatCapacity", 710.0);
        Settings::instance()->setSetting("C/HeatConductivity", 95);

        //************************************************************************************************************************
        //************************************************************************************************************************
        Settings::instance()->setSetting("Ar/Density", 1.5711);
        Settings::instance()->setSetting("Ar/HeatCapacity", 521.8428);
        Settings::instance()->setSetting("Ar/HeatConductivity", 0.055);

        //************************************************************************************************************************
        // Очертания тигля.
        //************************************************************************************************************************
        Settings::instance()->setSetting("Crucible/R", QVariantList() << 0.000 << 0.055 << 0.000 << 0.050 << 0.000 << 0.050
            << 0.055 << 0.000 << 0.050 << 0.010 << 0.055 << 0.000 << 0.010 << 0.055);
        Settings::instance()->setSetting("Crucible/Z", QVariantList() << 0.000 << 0.055 << 0.005 << 0.055 << 0.105 << 0.105
            << 0.105 << 0.110 << 0.110 << 0.115 << 0.115 << 0.165 << 0.165 << 0.000);
        Settings::instance()->setSetting("Crucible/N", QVariantList() << 44 << 3 << 3 << 39 << 78 << 39 << 44 << 39 << 3 << 3
            << 3 << 7 << 39 << 3 << 39 << 5 << 39 << 39 << 5 << 44 << 44);
    }
    if(Settings::instance()->setting("AppVersion").toString() != qApp->applicationVersion())
    {
    }

    Settings::instance()->sync();

    CylinderConeTt solver;
    solver.solve();

    cout << QObject::tr("Работа программы успешно завершена!") << endl;
    Settings::deinit();
    Log::deinit();

    return 0;
}
